<?php

namespace app\api\logic;

use app\common\exception\BusinessException;
use app\common\model\AppConfig;
use app\common\model\UserScoreRecord;
use app\common\service\UserService;

/**
 * Class ScoreActivity
 * @package app\api\logic
 */
class ScoreActivity
{
    /**
     * config
     * @var array
     */
    private $config = [];

    public function getConfig(): array
    {
        return $this->config;
    }

    /**
     * source_map
     * @var string[]
     */
    public array $source_map = [
        '1' => [
            'name' => '注册账号',
            'score' => 500,
            'check_func' => '',
        ],
        '2' => [
            'name' => '登录账号',
            'score' => 100,
            'check_func' => 'check_login',
        ],
        '3' => [
            'name' => '绑定微信',
            'score' => 100,
            'check_func' => 'check_bind',
        ],
        '4' => [
            'name' => '绑定邮箱',
            'score' => 300,
            'check_func' => 'check_bind',
        ],
        '5' => [
            'name' => '分享好友',
            'score' => 1000,
            'check_func' => ''
        ],
        '6' => [
            'name' => '普通签到',
            'score' => 10,
            'check_func' => '',
        ],
        '7' => [
            'name' => '连续签到',
            'score' => 20,
            'check_func' => '',
        ],
        '8' => [
            'name' => '激励视频',
            'score' => 50,
            'check_func' => 'check_reward',
        ],
        '9' => [
            'name' => '桌面访问',
            'score' => 300,
            'check_func' => 'check_desktop',
        ],
        '10' => [
            'name' => '收藏访问',
            'score' => 300,
            'check_func' => 'check_desktop',
        ],
        '11' => [
            'name' => '绑定公众号',
            'score' => 300,
            'check_func' => 'check_bind',
        ],
        '12' => [
            'name' => '绑定手机',
            'score' => 300,
            'check_func' => 'check_bind',
        ],
        '13' => [
            'name' => '扫码加群',
            'score' => 5000,
            'check_func' => 'check_source',
        ],
        '14' => [
            'name' => '公众号签到',
            'score' => 50,
            'check_func' => '',
        ],
        '15' => [
            'name' => '24小时点击',
            'score' => 200,
            'check_func' => '',
        ],
        '16' => [
            'name' => '注册用户点击',
            'score' => 100,
            'check_func' => '',
        ],
    ];

    /**
     * 初始化配置
     * @return $this
     * @throws BusinessException
     */
    public function initConfig($appId)
    {
        if (!$appId) {
            $appId = getAppId();
        }
        $this->config = app(AppConfig::class)->getByIdAndType($appId, 'score_rule');
        if (!$this->config) {
            throw new BusinessException('积分规则未配置');
        }
        foreach ($this->source_map as $key => $item) {
            $configKey = 'scene' . $key;
            $this->source_map[$key]['score'] = $this->config[$configKey] ?? 0;
        }
        return $this;
    }

    /**
     * send
     * @param int $uid
     * @param int $source
     * @param int $sendScore
     * @throws BusinessException
     */
    public function send(int $uid, int $source, int $sendScore = 0)
    {
        // 提取参数
        $source_map = $this->source_map[$source] ?? [];
        if (!$source_map) {
            throw new BusinessException('活动场景值不存在');
        }
        $score = $sendScore ?: $source_map['score'];

        // 检查函数
        $check_pass = true;
        $check_func = $source_map['check_func'];
        if ($check_func) {
            $check_pass = call_user_func([$this, $check_func], $uid, $source);
        }
        if ($check_pass) {
            // 赠送积分
            // 检查用户总积分
            $userService = new UserService();
            $userInfo = $userService->getUserById($uid);
            if (!$userInfo) {
                throw new BusinessException('未获取到当前用户信息');
            }
            if ($userInfo['score'] >= 500000) {
                throw new BusinessException('您的积分已超过500000限制');
            }
            $userService->sendScoreToUid($uid, $score, $source);
        }
        return $check_pass;
    }

    /**
     * check_login
     * @param $uid
     * @param $source
     * @return bool
     */
    private function check_login($uid, $source): bool
    {
        $s_time = mktime(0, 0, 0);
        $e_time = strtotime('+1 day', $s_time);
        $userScoreRecord = new UserScoreRecord();
        $where = [
            ['uid', '=', $uid],
            ['source', '=', $source],
            ['type', '=', 1],
            ['add_time', 'between', [$s_time, $e_time]],
        ];
        return (bool)$userScoreRecord->where($where)->count();
    }

    /**
     * check_bind
     * @param $uid
     * @param $source
     * @return bool
     */
    private function check_bind($uid, $source): bool
    {
        $userScoreRecord = new UserScoreRecord();
        $where = [
            ['uid', '=', $uid],
            ['source', '=', $source],
            ['type', '=', 1]
        ];
        return !(bool)$userScoreRecord->where($where)->count();
    }

    /**
     * check_source
     * @param $uid
     * @param $source
     * @return bool
     */
    public function check_source($uid, $source): bool
    {
        $userScoreRecord = new UserScoreRecord();
        $where = [
            ['uid', '=', $uid],
            ['source', '=', $source],
            ['type', '=', 1]
        ];
        return !(bool)$userScoreRecord->where($where)->count();
    }

    /**
     * check_reward
     * @param $uid
     * @param $source
     * @return bool
     */
    private function check_reward($uid, $source): bool
    {
        $s_time = mktime(0, 0, 0);
        $e_time = strtotime('+1 day', $s_time);
        $userScoreRecord = new UserScoreRecord();
        $where = [
            ['uid', '=', $uid],
            ['source', '=', $source],
            ['type', '=', 1],
            ['add_time', 'between', [$s_time, $e_time]],
        ];
        $count = $userScoreRecord->where($where)->count();
        if ($count >= 10) {
            return false;
        }
        return true;
    }

    /**
     * check_desktop
     * @param $uid
     * @param $source
     * @return bool
     */
    public function check_desktop($uid, $source): bool
    {
        $userScoreRecord = new UserScoreRecord();
        $where = [
            ['uid', '=', $uid],
            ['source', '=', $source],
            ['type', '=', 1]
        ];
        return !(bool)$userScoreRecord->where($where)->count();
    }


}